package com.countertack.dynamicinstrumentation;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.net.InetAddress;
import java.sql.ResultSet;

import org.doublecloud.vi.vmware.guest.GuestProcessDirector;

import com.countertack.impala.ImpalaConnector;
import com.countertack.ssh.SSHManager;
import com.countertack.utils.Configuration;
import com.countertack.utils.CustomFileFilter;
import com.countertack.utils.HttpClientUtils;
import com.countertack.utils.Utils;
import com.countertack.vmware.VMWareConnector;
import com.vmware.vim25.mo.VirtualMachine;

public class RunningScripts {
	public static void main(String[] args) throws Exception {
		StringBuffer diResult = new StringBuffer();
		String sentenelIp = null;
		String vmName = null;
		long st = System.currentTimeMillis();
		try {
			 if (args.length <= 0) {
			
			 System.out.println("configuration details missed !");
			 return;
			 }
			 String configFilePath = args[0];

			//String configFilePath = "C:\\Users\\user\\Desktop\\config.properties";

			Configuration.loadProperties(configFilePath);
			ImpalaConnector iConnector;

			iConnector = ImpalaConnector
					.createImpalaConnectorInstance(Configuration
							.getProperty("sentinelehost"));

			InetAddress address = InetAddress.getByName(Configuration
					.getProperty("sentinelehost"));
			sentenelIp = address.getHostAddress();
			diResult.append("Sentinel:::" + sentenelIp + "\n");
			System.out.println(address.getHostAddress());
			String vmUser = Configuration.getProperty("vmuser");

			String vmPassword = Configuration.getProperty("vmpassword");
			String scriptFilesLocation = Configuration.getProperty("discripts");
			String[] disnapshots = Configuration.getProperty("disnapshots")
					.split(",");

			VMWareConnector esxiConnector = new VMWareConnector(
					Configuration.getProperty("esxi"));
			VirtualMachine vm = esxiConnector
					.getVirtualMachineByname(Configuration
							.getProperty("vmname"));
			vmName = Configuration.getProperty("vmname");

			String endpointMachineStatus = esxiConnector
					.getVirtualMachineStatus(vm);

			if (endpointMachineStatus == null) {

				System.out.println("Power on  endpoint machine .....");

				esxiConnector.startVirtualMachine(vm);

				Thread.sleep(600000);

			} else {

				if ("notRunning".equalsIgnoreCase(endpointMachineStatus)) {

					esxiConnector.reStartVirtualMachine(vm);

					System.out.println("Rebooting endpoint machine .....");

					Thread.sleep(600000);

				}

			}

			String vmIp = Configuration.getProperty("vmip");

			if (vmIp == null) {

				vmIp = vm.getGuest().ipAddress;

			}
			System.out.println("VM Ip Address>>>" + vmIp);
			diResult.append("VM Ip Address>>>" + vmIp + "\n");
			for (String snapName : disnapshots) {
				diResult.append("<-------------snapshotname----->" + snapName
						+ "\n");
				boolean reConSt = false;
				;
				while (!reConSt) {
					System.out.println("initialising esxi");
					reConSt = esxiConnector.reconnectToEsxi();
					vm = esxiConnector.getVirtualMachineByname(vmName);
					Thread.sleep(30000);
				}

				while (true) {
					try {
						System.out.println("revert snap shot while loop");
						esxiConnector.revertToSnapShort(vm.getSnapshot()
								.getRootSnapshotList(), snapName);
						break;
					} catch (Exception ree) {
						ree.printStackTrace();
						System.out.println("Exception in reverting snap shot");
						Thread.sleep(30000);
						continue;

					}

				}

				System.out.println("Reverting to  snap shot>>>>>" + snapName);
				diResult.append("Reverting to  snap shot>>>>>" + snapName
						+ "\n");

				diResult.append("VM Name>>>>>" + vmName + "\n");
				diResult.append("SNAPSHOT NAME>>>>>" + snapName + "\n");
				diResult.append("TCPIP_NTOS>>>>>" + snapName + "\n");

				// SNAPSHOT NAME

				Thread.sleep(180000);

				endpointMachineStatus = esxiConnector
						.getVirtualMachineStatus(vm);

				if (endpointMachineStatus == null) {

					System.out.println("Power on  endpoint machine .....");
					diResult.append("Power on  endpoint machine ....." + "\n");

					esxiConnector.startVirtualMachine(vm);

					Thread.sleep(600000);

				} else {

					if ("notRunning".equalsIgnoreCase(endpointMachineStatus)) {

						esxiConnector.reStartVirtualMachine(vm);

						System.out.println("Rebooting endpoint machine .....");

						Thread.sleep(600000);

					}

				}

				SSHManager vmSsh = new SSHManager(vmUser, vmPassword, vmIp);
				vmSsh.connect();
				String tcpIpSymbol = Utils.getTcpIPSymbol(vmSsh);
				String ntosSymbol = Utils.getNtosKrnlSymbol(vmSsh);
				diResult.append("TCPIP Symbol_NTOS Symbol>>>>>" + tcpIpSymbol
						+ "_" + ntosSymbol + "\n");

				// installing agent

				vmSsh.copyFile(Configuration.getProperty("driverpath"),
						"CounterTack Agent Installer Hiding.exe");

				vmSsh.runCommand("cmd /c \"C:\\Users\\"
						+ vmUser
						+ "\\CounterTack Agent Installer Hiding.exe\" /S /HOST:"
						+ sentenelIp + " /PORT:443");

				System.out.println("Installing agent on endpoint");
				diResult.append("Installing agent on endpoint" + "\n");
				Thread.sleep(120000);

				String eId = null;
				ResultSet endpointIdRes = iConnector
						.executeQueryAndReturnResults("select id from endpoints where ip='"
								+ vm.getGuest().ipAddress
								+ "'"
								+ " and status='ON' and ip is not null order by time_started asc limit 1");

				while (endpointIdRes.next()) {
					try {
						eId = endpointIdRes.getString(1);
					} catch (Exception e) {

					}

					System.out.println("endpoint Id>>>>>>" + eId);
					diResult.append("endpoint Id>>>>>>" + eId + "\n");

				}

				if (eId == null) {

					System.out.println("endpoint is not installed");
					diResult.append("endpoint is not installed" + "\n");
					continue;
					// addResultsToLog(testCaseResult);

				}

				String driverVersion = getDriverVersion(eId, iConnector);
				diResult.append("Kernal Module Version:::::::" + driverVersion
						+ "\n");

				pauseEndpoint(eId);

				Thread.sleep(60000);
				String eStatus = getEndpointStatus(eId, iConnector);
				if (eStatus != null && "PAUSE".equalsIgnoreCase(eStatus)) {

					System.out.println("Endpoint paused successfully");
					diResult.append("Endpoint paused successfully" + "\n");
				} else {
					System.out.println("Endpoint not paused");
					diResult.append("Endpoint not paused" + "\n");

				}

				resumeEndpoint(eId);
				Thread.sleep(60000);

				eStatus = getEndpointStatus(eId, iConnector);
				if (eStatus != null && "ON".equalsIgnoreCase(eStatus)) {

					System.out.println("Resume endpoint success");
					diResult.append("Resume endpoint success" + "\n");
				} else {

					System.out.println("Resume endpoint failed");
					diResult.append("Resume endpoint failed" + "\n");

				}

				File diScripts = new File(scriptFilesLocation);

				if (diScripts.exists()) {

					File[] psFiles = diScripts.listFiles(new CustomFileFilter(
							".ps1"));

					if (psFiles.length <= 0) {

						System.out.println("no scripts to execute");
						diResult.append("no scripts to execute" + "\n");
						addResultsToLog(diResult);
						return;

					}
					for (File script : psFiles) {

						vmSsh.copyFile(script.getPath(), script.getName());

					}
					diResult.append("<=====Entering DI Scripts Execution =====>"
							+ "\n");
					for (File script : psFiles) {
						diResult.append("<=====" + script.getName() + "=====>"
								+ "\n");
						GuestProcessDirector progDir = null;

						while (true) {
							System.out.println("Inside Program Dir while loop");
							try {
								progDir = new GuestProcessDirector(vm, vmUser,
										vmPassword);

							} catch (Exception e3) {
								try {
									e3.printStackTrace();
									System.out.println("Reconnecting to esxi");
									esxiConnector.reconnectToEsxi();
									vm = esxiConnector
											.getVirtualMachineByname(vmName);
									progDir = new GuestProcessDirector(vm,
											vmUser, vmPassword);
									continue;
								} catch (Exception e2) {

									e2.printStackTrace();
								}

							}
							if (progDir != null) {

								break;
							}
							System.out
									.println("Waiting to reconnect to esxi for getting command process");
							Thread.sleep(30000);

						}

						try {
							progDir.run(
									"C:\\Windows\\System32\\cmd.exe",
									"net use z: \\\\10.140.62.45\\qa\\dijavaautomation_bsod /u:"
											+ Configuration
													.getProperty("countertackuser")
											+ " "
											+ Configuration
													.getProperty("countertackpassword"));
							Thread.sleep(30000);

						} catch (Exception e) {

							e.printStackTrace();
						}
						while (true) {

							try {
								progDir.run(
										"C:\\Windows\\System32\\cmd.exe",
										"/c powershell -ExecutionPolicy Unrestricted C:\\Users\\"
												+ Configuration
														.getProperty("vmuser")
												+ "\\" + script.getName());
								break;

							} catch (Exception e4) {
								System.out
										.println("exception in running script");
								e4.printStackTrace();
								try {
									esxiConnector.reconnectToEsxi();
									vm = esxiConnector
											.getVirtualMachineByname(vmName);
									progDir = new GuestProcessDirector(vm,
											vmUser, vmPassword);

								} catch (Exception wer) {
									System.out.println("Exceptio>>>"
											+ wer.getMessage());

								}

							}

						}

						String name = script.getName().toLowerCase();
						if (name.contains("cpu") || name.contains("memory")) {

							Thread.sleep(420000);
							System.out.println("completed success fully......"
									+ script.getName());
							diResult.append("completed success fully......"
									+ script.getName() + "\n");

						} else {

							Thread.sleep(720000);
							System.out.println("completed success fully......"
									+ script.getName());
							diResult.append("completed success fully......"
									+ script.getName() + "\n");

						}
						// checking bsod
						boolean isbsod = false;
						/*
						 * endpointMachineStatus = esxiConnector
						 * .getVirtualMachineStatus(vm);
						 */
						while (true) {
							System.out.println("inside while loop");
							try {
								endpointMachineStatus = esxiConnector
										.getVirtualMachineStatus(vm);

							} catch (Exception e) {

								e.printStackTrace();
								System.out
										.println("Reconnecting to esxi for checking bsod");
								try {
									esxiConnector.reconnectToEsxi();
									vm = esxiConnector
											.getVirtualMachineByname(vmName);
								} catch (Exception e2) {

									e2.printStackTrace();
								}

							}

							if ("Running"
									.equalsIgnoreCase(endpointMachineStatus)) {

								String bsodRes = vmSsh
										.returnCommandOutPut("cmd /c cd C:\\Windows && dir /b /a-d");

								if (bsodRes != null && bsodRes != "") {

									if (bsodRes.contains("MEMORY.dump")) {

										isbsod = true;

									}
									break;

								}
								Thread.sleep(120000);
							} else {
								System.out
										.println("Vm stopped after script execution restarting for checking BSOD");
								diResult.append("Vm stopped after script execution restarting for checking BSOD"
										+ "\n");
								esxiConnector.reStartVirtualMachine(vm);
								Thread.sleep(300000);

							}
						}

						if (isbsod) {
							try {

								progDir.run("C:\\Windows\\System32\\cmd.exe",
										"mkdir z:\\" + vm.getName()
												+ "_DI_BSOD_" + snapName);
							} catch (Exception e) {

								e.printStackTrace();
							}
							try {
								progDir.run("C:\\Windows\\System32\\cmd.exe",
										"copy c:\\Windows\\MEMORY.dump z:\\"
												+ vm.getName() + "_DI_BSOD_"
												+ snapName + "\\"
												+ "MEMORY.dump");
								Thread.sleep(60000);
								diResult.append("BSOD::::TRUE" + "\n");
								diResult.append("BSOD Location:::\\\\10.140.62.45\\qa\\dijavaautomation_bsod\\"
										+ vm.getName()
										+ "_DI_BSOD_"
										+ snapName
										+ "_" + "MEMORY.dump" + "\n");

							} catch (Exception e) {

								e.printStackTrace();
							}
							break;

						} else {
							diResult.append("BSOD:::False \n");
							diResult.append("BSOD LOcation::: \n");

						}

						// checking communication
						System.out.println("After running  script>>" + name);
						diResult.append("After running  script>>" + name + "\n");
						pauseEndpoint(eId);

						Thread.sleep(120000);
						eStatus = getEndpointStatus(eId, iConnector);
						if (eStatus != null
								&& "PAUSE".equalsIgnoreCase(eStatus)) {

							System.out.println("Endpoint paused successfully");
							diResult.append("Endpoint paused successfully"
									+ "\n");
						} else {
							System.out.println("Endpoint not paused");
							diResult.append("Endpoint not paused" + "\n");
							diResult.append("Sentinel communication failed"
									+ "\n");

							try {
								CopyFlumeLogTo45(sentenelIp, snapName, vmName);
							} catch (Exception cpe) {

								cpe.printStackTrace();
							}

							diResult.append("FlumeLogPath>>>"
									+ "\\\\10.140.62.45\\qa\\dijavaautomation_bsod\\"
									+ vmName + "_DI_Flume_log_" + snapName
									+ "\\flume.log" + "\n");

							break;

						}

						resumeEndpoint(eId);
						Thread.sleep(120000);

						eStatus = getEndpointStatus(eId, iConnector);
						if (eStatus != null && "ON".equalsIgnoreCase(eStatus)) {

							System.out.println("Resume endpoint success");
							diResult.append("Resume endpoint success" + "\n");
						} else {
							diResult.append("Sentinel communication failed"
									+ "\n");
							System.out.println("Resume endpoint failed");
							diResult.append("Resume endpoint failed" + "\n");
							try {
								CopyFlumeLogTo45(sentenelIp, snapName, vmName);
							} catch (Exception cpe) {

								cpe.printStackTrace();
							}
							diResult.append("FlumeLogPath>>>"
									+ "\\\\10.140.62.45\\qa\\dijavaautomation_bsod\\"
									+ vmName + "_DI_Flume_log_" + snapName
									+ "\\flume.log");
							break;

						}
						try {
							progDir.run("C:\\Windows\\System32\\cmd.exe",
									"net use z: /delete");
							Thread.sleep(30000);

						} catch (Exception e) {

							e.printStackTrace();
						}

					}

				} else {

					System.out.println("No scripts to execute");
					diResult.append("No scripts to execute" + "\n");
					addResultsToLog(diResult);
					return;
				}

			}
			System.out.println("Execution completed");
			diResult.append("Execution completed");
			addResultsToLog(diResult);
		} finally {

			addResultsToLog(diResult);

		}
		System.out.println("Total time taken>>>>"
				+ (System.currentTimeMillis() - st));

	}

	public static void pauseEndpoint(String eid) throws Exception {

		String pause = "{ " + "  \"type\":\"pause_many\", "
				+ "  \"endpoints\":[ " + "\"" + eid + "\" " + " ] " + "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", pause);

	}

	public static void main1(String[] args) throws Exception {

		Configuration.loadProperties("config.properties");
		CopyFlumeLogTo45("s13.dev.countertack.com", "wertyu", "ctest");

	}

	public static void CopyFlumeLogTo45(String sentinelIp, String snapName,
			String vmName) throws Exception {

		SSHManager sentenelSsh = new SSHManager("root", "f00b@r", sentinelIp);

		sentenelSsh.connect();
		sentenelSsh.downloadFile(
				"/var/log/flume-ng/flume-cmf-flume1-AGENT-"
						+ Configuration.getProperty("sentinelehost") + ".log",
				"flume-cmf-flume1-AGENT-"
						+ Configuration.getProperty("sentinelehost") + ".log");
		Thread.sleep(90000);

		/*
		 * \\\\10.140.62.45\\qa\\dijavaautomation_bsod\\" + vm.getName() +
		 * "_DI_BSOD_" + snapName + "_" + "MEMORY.dump"
		 */

		File flumeLogDir = new File(
				"\\\\10.140.62.45\\qa\\dijavaautomation_bsod\\" + vmName
						+ "_DI_Flume_log_" + snapName);

		flumeLogDir.mkdir();

		File logFile = new File("\\\\10.140.62.45\\qa\\dijavaautomation_bsod\\"
				+ vmName + "_DI_Flume_log_" + snapName + "\\flume.log");
		logFile.createNewFile();
		File sourceLogFile = new File("flume-cmf-flume1-AGENT-"
				+ Configuration.getProperty("sentinelehost") + ".log");
		System.out.println("source log>>" + sourceLogFile.getName());

		// flume-cmf-flume1-AGENT-s13.dev.countertack.com

		FileReader fReader = null;
		FileWriter fWriter = null;
		try {

			fReader = new FileReader(sourceLogFile);
			fWriter = new FileWriter(logFile);
			int c = fReader.read();

			while (c != -1) {

				fWriter.write(c);
				c = fReader.read();
			}

		} catch (Exception e) {

			e.printStackTrace();

		} finally {
			try {
				if (fReader != null) {

					fReader.close();
				}

			} catch (Exception e1) {

			}
			try {
				if (fWriter != null) {

					fWriter.close();
				}

			} catch (Exception e2) {

			}

			sentenelSsh.closeSession();
			sentenelSsh.doReconnect = false;
			System.out.println("completed");

		}
	}

	public static void resumeEndpoint(String eid) throws Exception {

		String resume = "{ " + "  \"type\":\"resume_many\", "
				+ "  \"endpoints\":[ " + "    \"" + eid + "\" " + "] " + "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", resume);

	}

	public static String getEndpointStatus(String eid,
			ImpalaConnector impalaConnector) {

		String status = null;
		ResultSet endpointStatRes = impalaConnector
				.executeQueryAndReturnResults("select status from endpoints where id='"
						+ eid + "'");
		try {
			while (endpointStatRes.next()) {
				try {
					status = endpointStatRes.getString(1);
				} catch (Exception e) {

				}

				System.out.println("endpoint status>>>>>>" + status);

			}
		} catch (Exception e) {

		}

		return status;

	}

	public static void addResultsToLog(StringBuffer vals) {
		File testCaseResFile = new File("DIPatchSet_result_"
				+ Configuration.getProperty("vmname") + ".txt");

		try {
			testCaseResFile.createNewFile();
			FileOutputStream fout = new FileOutputStream(testCaseResFile);

			//

			fout.write(vals.toString().getBytes());

			fout.flush();
			fout.close();

		} catch (Exception e) {

			e.printStackTrace();

		}

	}

	public static String getDriverVersion(String eid, ImpalaConnector iConnector) {

		String driver_Version = null;
		ResultSet endpointStatRes = iConnector
				.executeQueryAndReturnResults("select driver_version from endpoints where id='"
						+ eid + "'");
		try {
			while (endpointStatRes.next()) {
				try {
					driver_Version = endpointStatRes.getString(1);
				} catch (Exception e) {

				}

				System.out.println("Driver version>>>>>>" + driver_Version);

			}
		} catch (Exception e) {

		}

		return driver_Version;

	}

}
